package drds.configuration.mvc.core;


import com.google.gson.Gson;
import drds.configuration.common.Constants;
import drds.configuration.mvc.render.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.util.Map;

//import tool.plus.mvc.render.*;

/**
 * 控制器.里面的方法直接操作具体的web对象--设计思路<br/>
 * Controller不支持POJO,同时约定:不对Controller的子类再次继承
 * <p>
 * <p>
 * 拦截器用法
 * <p>
 * <pre>
 * &#064;ActionKey(&quot;/user/user&quot;)
 * public class UserAction extends Controller {
 * 	&#064;AllowNotLogin
 * 	&#064;ClearInterceptor(ClearLayer.Before)
 * 	&#064;Before({ UserLoginedAop.class })
 * 	public void test1() {
 *  }
 *
 * 	&#064;AllowNotLogin
 * 	&#064;ClearInterceptor(ClearLayer.Before)
 * 	&#064;Before({ Ajax.class, UserLoginedAjax.class })
 * 	public void test2() {
 *  }
 * }
 *
 * </pre>
 */
// request里面取出数据并且可以进行转换特定的数据类型：Boolean,Byte,Short,Integer,Long,Float,Double
public abstract class Controller {


    public static Logger logger = LoggerFactory.getLogger(Controller.class);
    public static Gson gson = new Gson();

    /**
     * request里面取出数据并且可以进行转换特定的数据类型：Boolean,Byte,Short,Integer,Long,Float,Double<br/>
     * request所有的方法<br/>
     * <p>
     * <pre>
     * {@link #getParameter(String, String)}
     * {@link #getParameterToInt(String)}
     * {@link #getParameterToInt(String, Integer)}
     * {@link #getParameterToInt(String, int)}
     * {@link #getParameterToLong(String)}
     * {@link #getParameterToLong(String, Long)}
     * {@link #getParameterToFloat(String)}
     * {@link #getParameterToFloat(String, Float)}
     * {@link #getParameterToDouble(String)}
     * {@link #getParameterToDouble(String, Float)}
     * </pre>
     */
    public String getParameter(String name) {
        HttpServletRequest request = ActionContext.getRequest();
        String value = request.getParameter(name);
        if (value == null) {
            return null;
        } else {
            return value.trim();
        }

    }

    public String getParameter(String name, String defaultValue) {
        HttpServletRequest request = ActionContext.getRequest();
        String result = request.getParameter(name);
        return result != null ? result.trim() : defaultValue;
    }

    public Double getParameterToDouble(String name) {
        String result = getParameter(name);
        return result != null ? Double.parseDouble(result.trim()) : null;
    }

    public Double getParameterToDouble(String name, Float defaultValue) {
        String result = getParameter(name);
        return result != null ? Double.parseDouble(result.trim()) : defaultValue;
    }

    public Float getParameterToFloat(String name) {
        String result = getParameter(name);
        return result != null ? Float.parseFloat(result.trim()) : null;
    }

    public Float getParameterToFloat(String name, Float defaultValue) {
        String result = getParameter(name);
        return result != null ? Float.parseFloat(result.trim()) : defaultValue;
    }

    public Integer getParameterToInt(String name) {
        String result = getParameter(name);
        return result != null ? Integer.parseInt(result.trim()) : null;
    }

    /**
     * 主要用到的一个函数.针对NullPointerException和NumberFormatException异常进行处理-0
     */
    public Integer getParameterToInt(String name, int defaultValue) {
        try {
            String result = getParameter(name);
            return result != null ? Integer.parseInt(result.trim()) : defaultValue;
        } catch (NullPointerException e) {
            if (Constants.devMode) {
                logger.debug(e.getMessage());
            }

            return defaultValue;
        } catch (NumberFormatException e) {
            if (Constants.devMode) {
                logger.debug(e.getMessage());
            }
            return defaultValue;
        }
    }

    /**
     * 主要用到的一个函数.针对NullPointerException和NumberFormatException异常进行处理-null
     */
    public Integer getParameterToInt(String name, Integer defaultValue) {
        try {
            String result = getParameter(name);
            return result != null ? Integer.parseInt(result.trim()) : defaultValue;
        } catch (NullPointerException e) {
            return null;
        } catch (NumberFormatException e) {
            return null;
        }
    }

    public Long getParameterToLong(String name) {
        String result = getParameter(name);
        return result != null ? Long.parseLong(result.trim()) : null;
    }

    public Long getParameterToLong(String name, Long defaultValue) {
        String result = getParameter(name);
        return result != null ? Long.parseLong(result.trim()) : defaultValue;
    }

    public Long getParameterToLong(String name, long defaultValue) {
        String result = getParameter(name);
        return result != null ? Long.parseLong(result.trim()) : defaultValue;
    }

    /**
     * 请求参数如果值不止一个的情况
     * <p>
     * <pre>
     * {@link #getParameterValuesToInt(String)}
     * {@link #getParameterValuesToLong(String)}
     * {@link #getParameterValuesToFloat(String)}
     * {@link #getParameterValuesToDouble(String)}
     * </pre>
     */
    public Map<String, String[]> getParameterValues() {
        HttpServletRequest request = ActionContext.getRequest();
        return request.getParameterMap();
    }

    public String[] getParameterValues(String name) {
        HttpServletRequest request = ActionContext.getRequest();
        return request.getParameterValues(name);
    }

    public Double[] getParameterValuesToDouble(String name) {
        HttpServletRequest request = ActionContext.getRequest();
        String[] values = request.getParameterValues(name);
        if (values == null) {
            return null;
        }
        Double[] result = new Double[values.length];
        for (int i = 0; i < result.length; i++) {
            result[i] = Double.parseDouble(values[i]);
        }
        return result;
    }

    public Float[] getParameterValuesToFloat(String name) {
        HttpServletRequest request = ActionContext.getRequest();
        String[] values = request.getParameterValues(name);
        if (values == null) {
            return null;
        }
        Float[] result = new Float[values.length];
        for (int i = 0; i < result.length; i++) {
            result[i] = Float.parseFloat(values[i]);
        }
        return result;
    }

    public Integer[] getParameterValuesToInt(String name) {
        HttpServletRequest request = ActionContext.getRequest();
        String[] values = request.getParameterValues(name);
        if (values == null) {
            return null;
        }
        Integer[] result = new Integer[values.length];
        for (int i = 0; i < result.length; i++) {
            result[i] = Integer.parseInt(values[i]);
        }
        return result;
    }

    public Long[] getParameterValuesToLong(String name) {
        HttpServletRequest request = ActionContext.getRequest();
        String[] values = request.getParameterValues(name);
        if (values == null) {
            return null;
        }
        Long[] result = new Long[values.length];
        for (int i = 0; i < result.length; i++) {
            result[i] = Long.parseLong(values[i]);
        }
        return result;
    }

    // ActionContext获取Render 避免线程安全
    public Render getRender() {
        return ActionContext.getRender();
    }

    /**
     * session处理
     * <p>
     * <pre>
     * {@link #getSession()}
     * {@link #getSession(boolean)}
     * {@link #getSessionAttribute(String)}
     * </pre>
     */
    public HttpServletRequest getRequest() {
        return ActionContext.getRequest();
    }

    public HttpServletResponse getResponse() {
        return ActionContext.getResponse();
    }

    public HttpSession getSession() {
        HttpServletRequest request = ActionContext.getRequest();
        return request.getSession();
    }

    public HttpSession getSession(boolean create) {
        HttpServletRequest request = ActionContext.getRequest();
        return request.getSession(create);
    }

    @SuppressWarnings("unchecked")
    public <T> T getSessionAttribute(String key) {
        HttpServletRequest request = ActionContext.getRequest();
        HttpSession session = request.getSession();
        return session != null ? (T) session.getAttribute(key) : null;
    }

    /**
     * string to int
     */
    public int getSessionAttributeToInt(String key, int defaultValue) {
        HttpServletRequest request = ActionContext.getRequest();
        HttpSession session = request.getSession();
        String value = (String) session.getAttribute(key);
        if (value == null) {
            return defaultValue;
        } else {
            try {
                return Integer.parseInt(value);
            } catch (Exception e) {
                return defaultValue;
            }

        }

    }

    public int getSessionAttribute(String key, int defaultValue) {
        HttpServletRequest request = ActionContext.getRequest();
        HttpSession session = request.getSession();
        Integer value = (Integer) session.getAttribute(key);
        try {
            return value.intValue();
        } catch (Exception e) {
            return value.intValue();
        }

    }

    public Controller removeAttribute(String name) {
        HttpServletRequest request = ActionContext.getRequest();
        if (request.getAttribute(name) != null) {
            request.removeAttribute(name);
        }
        return this;
    }

    public Controller removeSessionAttribute(String key) {
        HttpServletRequest request = ActionContext.getRequest();
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.removeAttribute(key);
        }
        return this;
    }

    public Controller setAttribute(String name, Object value) {
        HttpServletRequest request = ActionContext.getRequest();
        request.setAttribute(name, value);
        return this;
    }

    public Controller setAttributeMap(Map<String, Object> attributeMap) {
        for (Map.Entry<String, Object> entry : attributeMap.entrySet()) {
            HttpServletRequest request = ActionContext.getRequest();
            request.setAttribute(entry.getKey(), entry.getValue());
        }
        return this;
    }

    public Controller setSessionAttribute(String key, Object value) {
        HttpServletRequest request = ActionContext.getRequest();
        request.getSession().setAttribute(key, value);
        return this;
    }

    // core-renders
    private void render(Render render) {
        ActionContext.setRender(render);
    }

    // render
    public void renderText(String text) {
        if (Constants.devMode) {
            logger.debug("输出返回响应值:" + text);
        }
        render(new TextRender(text));
    }

    /**
     * 将map自动转换为json字符串
     */
    public void renderJson(Map<String, Object> map) {
        render(new JsonRender(map));
    }

    public void renderAction(String text) {
        render(new ActionRender(text));
    }

    public void renderFile(File file, String fileName) {
        render(new FileRender(file, fileName));
    }

    public void renderJsp(String jsp) {
        render(new RootRender(jsp));
    }

    public void renderHttp(String url) {
        render(new HttpRender(url));
    }

    public void noRender() {
        render(new NullRender());
    }

    /**
     * 获取系统的根路径
     */

    public String getContextPath() {
        ServletContext context = getRequest().getSession().getServletContext();
        return context.getRealPath("/");
    }

}